/**
 * Project: apollo-base-dal
 * 
 * File Created at 2016年5月6日
 * 
 * Copyright 2015-2016 dx.com Croporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * DongXue software Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with dx.com.
 */
package com.dx.pf.dal.jdbc.sql;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import com.dx.pf.dal.Logger;
import com.dx.pf.dal.constants.DalConstant;
import com.dx.pf.dal.constants.OrderBy;

/**
 * @ClassName: SqlSelect
 * @Description: 查询语句的helper
 * @author wuzhenfang(wzfbj2008@163.com)
 * @date 2016年5月6日 上午10:26:49
 * @version V1.0
 */
public class SqlHelperSelect extends SqlOperator {
	
	private final static Logger logger = Logger.getLogger(SqlHelper.class);
	/**查询sql*/
	private StringBuilder selectsql = new StringBuilder(128);
	/**查询列表sql*/
	private StringBuilder selCoumn = null;
	/**where部分*/
	private StringBuilder selwhere = new StringBuilder(64);
	/**排序部分*/
	private StringBuilder selOrderBy = new StringBuilder(32);
	/**分页sql*/
	private StringBuilder selPage = null;
	/**count统计部分*/
	private String selCount = null;
	 
	private boolean count = true;//是否为统计count
	
	public SqlHelperSelect(SqlHelper sqlHelper ,Class<?> clazz) {
		super(sqlHelper,clazz);
		selectsql = new StringBuilder("SELECT ");
	}
	
	/**
	 * 设置查询列表重复设置会覆盖前设置的查询列表
	 * @param columnNames
	 * @return
	 */
	public SqlHelperSelect setSeleteFields(String... columnNames) {
		selCoumn = new StringBuilder(128);
		// 传入的查询字段列表为空
		if (null == columnNames || columnNames.length < 1) {
			List<String> colList = entryInfo.getColNameList();
			columnNames = colList.toArray(new String[colList.size()]);// FIXME 效率不高啊，这样转换
		}
		// 解析查询字段列表
		boolean flag = false;
		for (String columnName : columnNames) {
			// TODO 验证字段是否合法，添加了也会影响效率，如果使用generation生成的entity就不会出现问题。
			if (flag) {
				selCoumn.append(DalConstant.sql_pause);
			}
			selCoumn.append(columnName);
			flag = true;
		}
		
		count = false;// 非统计
		selCount = null;
		return this;
	}

	/**
	 * 统计数量
	 * @return
	 */
	public SqlHelperSelect count() {
		if (count) {
			selCount = "COUNT(1) ";
		} else {
			logger.error("设置过查询，非count操作，不允许再次设置。");
		}
		count = true;// 统计
		selCoumn = null;
		return this;
	}
	
	/**
	 * 设置where条件
	 * @param condi
	 * @return
	 */
	public SqlHelperSelect setWhere(Condition condition) {
		selwhere.append(DalConstant.sql_Where).append(condition.getCondiSQL());
		putAllexecuteMap(condition.getConditionParam());
		return this;
	}
	
	/**
	 * 设置添加并累计多个排序字段
	 * @param columnName
	 * @param orderBy
	 * @return
	 */
	public SqlHelperSelect addOrderBy(String columnName,OrderBy orderBy){
		if(selOrderBy.length() > 0){
			selOrderBy.append(",");
		}else{
			selOrderBy.append(" ORDER BY ");
		}
		selOrderBy.append(columnName).append(" ").append(orderBy.getSqlVal());
		return this;
	}
	
	/**
	 * 设置分页
	 * @param pageNo 取得当前页显示的项的起始序号 (1-based)
	 * @param pageSize
	 * @return
	 */
	public SqlHelperSelect setPage(int pageNo, int pageSize) {
		int beginIndex = 0;
		if (pageNo > 0) {
			beginIndex = (pageSize * (pageNo - 1));
		}else{
			logger.error("设置页面属性错误", new SQLException("设置页面属性错误"));
		}
		selPage = new StringBuilder(" LIMIT ").append(beginIndex).append(DalConstant.sql_pause).append(pageSize);
		return this;
	}
	
	/**
	 * 设置执行参数
	 */
	@Override
	protected void putAllexecuteMap(Map<String, Object> paramMap) {
		super.getExecuteMap().putAll(paramMap);
	}

	//SELECT ... FROM ... WHERE ... ORDER BY ... LIMIT ...  
	@Override
	public SqlHelper builder() {
		if (count) {
			selectsql.append(selCount);
		} else {
			if (null == selCoumn) {
				setSeleteFields(new String[] {});
			}
			selectsql.append(selCoumn);
		}
		selectsql.append(DalConstant.sql_from).append(super.tableName).append(" ");
		selectsql.append(selwhere);
		selectsql.append(selOrderBy);
		selectsql.append(selPage);
		super.sql.append(selectsql);
		logger.debug(super.sql.toString());
		return super.sqlHelper;
	}

}
